#pragma once

#include <memory>
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

#define SelfDefine 1

const std::string ProtSep = " ";
const std::string LineBreakSep = "\r\n";  // 这里使用telnet模拟客户端，所以行分割符\r\n

// "len\nx op y\n"
// "len\nresult code\n"
// 添加自描述报头 len代表报文的长度，不包含后面的\n
// 解决用户区分报文边界问题
std::string EnCode(const std::string &info)
{
    std::string message = std::to_string(info.size()) + LineBreakSep + info + LineBreakSep;
    return message;
}

// "l"
// "len"
// "len\n"
// "len\nx"
// "len\nx op "
// "len\nx op y"
// "len\nx op y\n"
// "len\nx op y\n""le"
// "len\nx op y\n""len\nx"
// "len\nx op y\n""len\nx op y\n"

// "len\nresult code\n""len\nresult code\n"
// 取出报文
bool DeCode(std::string &message, std::string *info)
{
    // 读到len
    auto pos = message.find(LineBreakSep);
    if (pos == std::string::npos)
        return false;

    std::string len = message.substr(0, pos);
    int messagelen = stoi(len);

    // 保证读到完整的报文
    int total = len.size() + messagelen + 2 * LineBreakSep.size();
    if (message.size() < total)
        return false;

    *info = message.substr(pos + LineBreakSep.size(),messagelen);
    
    // 对已经读完的报文，再message中删除
    message.erase(0, total);

    return true;
}

// 请求
class Request
{
public:
    Request()
    {
    }
    Request(int data_x, int data_y, char op)
        : _data_x(data_x), _data_y(data_y), _oper(op)
    {
    }

    void Debug()
    {
        std::cout << _data_x << " " << _oper << " " << _data_y << std::endl;
    }

    void Test()
    {
        _data_x++;
        _data_y++;
    }

    // x op y
    // 序列化
    bool Serialize(std::string *out)
    {
#ifdef SelfDefine
        // 自己设计的反序列化方案
        *out = std::to_string(_data_x) + ProtSep + _oper + ProtSep + std::to_string(_data_y);
        return true;
#else
        // 成熟的Json序列化方案
        Json::Value root;
        root["data_x"] = _data_x;
        root["data_y"] = _data_y;
        root["oper"] = _oper;

        Json::FastWriter writer;
        *out = writer.write(root);

        return true;
#endif
    }
    // x op y
    // 反序列化
    bool Deserialize(const std::string &in)
    {
#ifdef SelfDefine
        // 自己设计的反序列化方案
        auto pos = in.find(ProtSep);
        if (pos == std::string::npos)
            return false;
        auto rpos = in.rfind(ProtSep);
        if (rpos == std::string::npos)
            return false;

        _data_x = stoi(in.substr(0, pos));
        _data_y = stoi(in.substr(rpos + ProtSep.size()));

        std::string op = in.substr(pos + ProtSep.size(), rpos - (pos + ProtSep.size()));
        if (op.size() != 1)
            return false;

        _oper = op[0];
        return true;
#else
        // 成熟的Json反序列化方案
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);

        _data_x = root["data_x"].asInt();
        _data_y = root["data_y"].asInt();
        _oper = root["oper"].asInt();

        return true;
#endif
    }

    int GetX()
    {
        return _data_x;
    }

    int GetY()
    {
        return _data_y;
    }

    char GetOp()
    {
        return _oper;
    }

private:
    int _data_x; // 第一个参数
    int _data_y; // 第一个参数
    char _oper;  // 操作符
};

// 响应
class Response
{
public:
    Response()
        : _result(0), _code(0)
    {
    }
    Response(int result, int code)
        : _result(result), _code(code)
    {
    }

    // result code
    // 序列化
    bool Serialize(std::string *out)
    {
#ifdef SelfDefine
        // 自己设计的序列化方案
        *out = std::to_string(_result) + ProtSep + std::to_string(_code);
        return true;

#else
        // 成熟的Json序列化方案
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::FastWriter writer;
        *out = writer.write(root);

        return true;
#endif
    }
    // result code
    // 反序列化
    bool Deserialize(const std::string &in)
    {
#ifdef SelfDefine
        // 自己设计的反序列化方案
        auto pos = in.find(ProtSep);
        if (pos == std::string::npos)
            return false;

        cout << "_result -------------------" << endl;
        _result = stoi(in.substr(0, pos));
        cout << "_code -------------------" << endl;
        _code = stoi(in.substr(pos + ProtSep.size()));

        return true;
#else
        // 成熟的Json反序列化方案
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);

        _result = root["result"].asInt();
        _code = root["code"].asInt();

        return true;
#endif
    }

    void SetResult(int reslut)
    {
        _result = reslut;
    }

    void SetCode(int code)
    {
        _code = code;
    }

    int GetResult()
    {
        return _result;
    }

    int GetCode()
    {
        return _code;
    }

private:
    int _result; // 答案
    int _code;   // 答案是否有效
};

// 工厂模式，建造类设计模式
class Factory
{
public:
    // 使用智能指针创建Request对象
    std::shared_ptr<Request> BuildRequest()
    {
        std::shared_ptr<Request> req = std::make_shared<Request>();

        return req;
    }
    std::shared_ptr<Request> BuildRequest(int data_x, int data_y, char op)
    {
        std::shared_ptr<Request> req = std::make_shared<Request>(data_x, data_y, op);

        return req;
    }

    // 使用智能指针创建Response对象
    std::shared_ptr<Response> BuildResponse()
    {
        std::shared_ptr<Response> resp = std::make_shared<Response>();

        return resp;
    }
    std::shared_ptr<Response> BuildResponse(int result, int code)
    {
        std::shared_ptr<Response> resp = std::make_shared<Response>(result, code);

        return resp;
    }
};